package com.ifyyf.es_study.service.impl;

import com.alibaba.fastjson.JSON;
import com.ifyyf.es_study.pojo.Content;
import com.ifyyf.es_study.service.ContentService;
import com.ifyyf.es_study.utils.HtmlParseUtil;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author if
 * @Description: What is it
 * @Date 2021-10-14 下午 08:28
 */
@Service
public class ContentServiceImpl implements ContentService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public boolean batchInsertFromJd(String key) throws IOException {
        BulkRequest bulkRequest=new BulkRequest();
        bulkRequest.timeout("3m");
        List<Content> contents = HtmlParseUtil.searchJd("java");
        for(int i=0;i<contents.size();i++){
            bulkRequest.add(new IndexRequest("jd_search")
                    .source(JSON.toJSONString(contents.get(i)), XContentType.JSON));
        }
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return !bulkResponse.hasFailures();
    }

    @Override
    public List<Map<String, Object>> searchByKeyWord(String key,int from,int size) throws IOException {
        List<Map<String, Object>> result=new ArrayList<>();
        SearchRequest searchRequest=new SearchRequest("jd_search");
        SearchSourceBuilder searchSourceBuilder =new SearchSourceBuilder();
        //因为中文在精确搜索时有问题，所以用的模糊matchQuery
        MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("title",key);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS))
                .query(termQueryBuilder)
                .from((from-1)*size)
                .size(size);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            result.add(hit.getSourceAsMap());
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> searchHighLight(String key,int from,int size) throws IOException {
        List<Map<String, Object>> result=new ArrayList<>();
        SearchRequest searchRequest=new SearchRequest("jd_search");
        SearchSourceBuilder searchSourceBuilder =new SearchSourceBuilder();
        //因为中文在精确搜索时有问题，所以用的模糊matchQuery
        MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("title",key);
        //高亮构造器
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        //是否需要多个参数高亮
        highlightBuilder.requireFieldMatch(false);
        //设置高亮字段
        highlightBuilder.field("title");
        //前标签
        highlightBuilder.preTags("<strong class='high-light' style='color:red'>");
        //后标签闭合
        highlightBuilder.postTags("</strong>");
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS))
                .query(termQueryBuilder)
                .from((from-1)*size)
                .size(size)
                .highlighter(highlightBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            //得到所有结果
            Map<String, Object> source = hit.getSourceAsMap();
            //获取高亮的字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("title");
            //解析高亮字段
            if(highlightField!=null){
                source.put(highlightField.getName(),highlightField.getFragments()[0].toString());
            }
            result.add(source);
        }
        return result;
    }
}
